import zlib



class Builder(object):
    _registry = {}
    PARAMS_PREFIX = None
    
    @classmethod
    def _register(cls, builder, extensions):
        for ext in extensions:
            if ext in cls._registry:
                logwarning("REGBUILDER", "%r already registered", ext)
            cls._registry[ext] = builder
            loginfo("REGBUILDER", "registered %r with %r", ext, builder)
    @classmethod
    def register(cls, *extensions):
        cls._register(cls, extensions)
    @classmethod
    def select(cls, ext):
        if ext not in cls._registry:
            raise NoRegisteredBuilder(ext)
        return cls._registry[ext]
    
    @classmethod
    def calc_file_crc(cls, filename, chunksize = 32000):
        crc = 0
        size = 0
        f = open(filename, "rb")
        while True:
            buf = f.read(chunksize)
            if not buf:
                break
            size += len(buf)
            crc = zlib.crc32(buf, crc)
        f.close()
        if crc < 0:
            crc += 2**32
        return "%08x%08x" % (size, crc)

    @classmethod
    def calc_params_crc(cls, params, prefix):
        crc = 0
        for name in dir(params):
            if name.startswith("prefix"):
                crc = zlib.crc32(repr(params[name]), crc)
        if crc < 0:
            crc += 2**32
        return "%08x" % (crc,)
        
    @classmethod
    def get_signature(cls, node):
        sig = cls.calc_file_crc(node.filename)
        if cls.PARAMS_PREFIX is not None:
            sig += cls.calc_params_crc(node.params, cls.PARAMS_PREFIX)
        return sig
    @classmethod
    def get_output(cls, node):
        pass
    @classmethod
    def scan(cls, node):
        pass
    @classmethod
    def build(cls, node):
        pass


class ResourceBuilder(Builder):
    def __init__(self, resource_ext, resource_builder = None):
        self.resource_ext = resource_ext
        self.resource_builder = resource_builder
    
    def scan(self, node):
        resname = node.basename + "." + self.resource_ext
        child = node.new_child(resname, builder = self.resource_builder)
        child._output = node.filename
        node._child = child
    
    def get_signature(self, node):
        return node._child.builder.get_signature(node._child)
    
    def register(self, *extensions):
        self._register(self, extensions)


class AutoBuilder(Builder):
    @classmethod
    def get_output(cls, node):
        return node._output


class ChainBuilder(Builder):
    def __init__(self, outer, inner):
        self.inner = inner
        self.outer = outer
    
    def scan(self, node):
        self.inner.scan(node)
        #self.outer.scan(node)
    
    def build(self, node):
        self.outer.build(node)


class BuildResult(object):
    def wait(self):
        pass
    
    def get_status(self):
        pass
    
    def get_report(self):
        pass




































